#ifndef WWBIZ_CONFIGURATION_MGR_H
#define WWBIZ_CONFIGURATION_MGR_H

#include "../Core/xparam.hpp"
#include "WWCommonUtility.h"
#include <string>

using std::string;
using namespace wwcommon;

class ConfigurationMgr
{
public:
    ConfigurationMgr()
    {
        m_common_config_file = FileUtility::GetWWGlobalCfgPath() + "/common_cfg.json";
        m_biz_config_file = FileUtility::GetWWGlobalCfgPath() + "/imbiz_cfg.json";
    }
    static ConfigurationMgr& Instance()
    {
        static ConfigurationMgr staticThis;
        return staticThis;
    }
    ~ConfigurationMgr()
    {
        SaveUserConfig();
    }
    bool LoadConfig()
    {
        bool ret1 = m_common_config.FromJsonFile(m_common_config_file);
        assert(ret1);
        bool ret2 = m_biz_config.FromJsonFile(m_biz_config_file);
        assert(ret2);
        return ret1 && ret2;
    }
    void LoadUserConfig(const std::string& uid)
    {
        m_user_config_file = FileUtility::MakeWWConfigPath(uid) + "/user_cfg.json";
        m_userid = uid;
        m_user_config.FromJsonFile(m_user_config_file);
    }
    void UnLoadUserConfig()
    {
        SaveUserConfig();
        m_user_config = core::XParam();
        m_userid.clear();
        m_user_config_file.clear();
    }
    void SaveUserConfig()
    {
        if(m_user_config_file.empty())
            return;
        m_user_config.ToJsonFile(m_user_config_file);
    }
    void Get_CommonConfig(const std::string& key, std::string& value)
    {
        m_common_config.get_Str(key, value);
    }
    void Get_BizConfig(const std::string& key, std::string& value)
    {
        m_biz_config.get_Str(key, value);
    }
    void Get_UserConfig(const std::string& key, std::string& value)
    {
        if(m_userid.empty())
            return;
        m_user_config.get_Str(key, value);
    }
    void Set_UserConfig(const std::string& key, const std::string& value)
    {
        if(m_userid.empty())
            return;
        m_user_config.put_Str(key, value);
    }
    void Get_CommonConfig(const std::string& key, int& value)
    {
        m_common_config.get_Int(key, value);
    }
    void Get_BizConfig(const std::string& key, int& value)
    {
        m_biz_config.get_Int(key, value);
    }
    void Get_UserConfig(const std::string& key, int& value)
    {
        if(m_userid.empty())
            return;
        m_user_config.get_Int(key, value);
    }
    void Set_UserConfig(const std::string& key, int value)
    {
        if(m_userid.empty())
            return;
        m_user_config.put_Int(key, value);
    }

private:
    core::XParam m_common_config;
    core::XParam m_biz_config;
    core::XParam m_user_config;
    std::string m_common_config_file;
    std::string m_biz_config_file;
    std::string m_user_config_file;
    std::string m_userid;
};

template<typename T> void IMGet_CommonConfig(const std::string& key, T& value)
{
    ConfigurationMgr::Instance().Get_CommonConfig(key, value);
}
template<typename T> void IMGet_BizConfig(const std::string& key, T& value)
{
    ConfigurationMgr::Instance().Get_BizConfig(key, value);
}
template<typename T> void IMGet_UserConfig(const std::string& key, T& value)
{
    ConfigurationMgr::Instance().Get_UserConfig(key, value);
}
template<typename T> void IMSet_UserConfig(const std::string& key, T value)
{
    ConfigurationMgr::Instance().Set_UserConfig(key, value);
}
#endif
